package com.gcsoftware.gateway.GWImpl;

import com.gcsoftware.gateway.utils.regrex.RegexUtils;
import com.gcsoftware.gw.beans.*;
import org.apache.commons.lang3.StringUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by qs on 2018/4/12.
 */
public class GwAccessControl {
    private static Map<String , Object> accessMap;

    public static final String ACCESS_SERVICE_NAME="gw-access-service-";
    public static final String ACCESS_SERVICE_ID="gw-access-serviceId-";
    public static final String ACCESS_SENS_ID="gw-sens-id-";
    public static final String ACCESS_SENS_NAME="gw-sens-name-";



    private static final String ADDR_REGEX ="http://(.*?):(.*)";;

    public static Map<String, Object> getAccessMap() {
        if (null == accessMap) {
            synchronized (GwAccessControl.class) {
                if (null == accessMap)  {
                    accessMap = new HashMap<>();
                }
            }
        }
        return accessMap;
    }
    public static void putRoleMap (GwAccessRole role) {
        getAccessMap().remove(role.getRoleId());

        Map<String , Object> urisMap = new HashMap<>();
        Map<String , Object> uriMap = new HashMap<>();
        Map<String, Object> serviceMap = null;
        for (GwAccessRoleUris uris: role.getGwAccessRoleUris()) {

            uriMap = new HashMap<>();
            for (GwAccessRoleUri uri:uris.getGwAccessRoleUri()) {
                serviceMap = new HashMap<>();
                for (GwAccessItems items : uri.getGwAccessItems()) {
                    serviceMap.put(ACCESS_SERVICE_ID+(null == items.getGwServiceId() ? "" : items.getGwServiceId()),initItemsMap(items.getGwAccessItem()));
                }
                uriMap.put(uri.getUri(),serviceMap);
            }
            if ("1".equals(uris.getGwAccessUnify()))
                uriMap.put(ACCESS_SERVICE_NAME + uris.getGwAccessInterf(), StringUtils.isBlank(uris.getGwAccessService())?"serviceId" : uris.getGwAccessService());
            urisMap.put(uris.getGwAccessInterf(),uriMap);
        }
        getAccessMap().put(role.getRoleId(),urisMap);
        getAccessMap().put(ACCESS_SENS_ID+role.getRoleId(),role.getGwAccessSensIds());
        getAccessMap().put(ACCESS_SENS_NAME+role.getRoleId(),role.getGwAccessSensNames());
    }

    private static Map<String, Object> initItemsMap(List<GwAccessItem> itemList) {
        Map<String, Object> fieldMap = new HashMap<>();
        if (null != itemList && itemList.size() > 0) {
            for (GwAccessItem item : itemList)  {
                if (0 == item.getGwIsabeld()) {
                    fieldMap.putAll(initFieldMap(item.getGwFieldname(), StringUtils.isEmpty(item.getGwSensValue()) ? RbacConsts.getDftValue(item.getGwFieldtype()): item.getGwSensValue() ,fieldMap));
                }
            }
        }
        return fieldMap;
    }

    private static Map<String , Object> initFieldMap(String fieldName,String sensValue, Map<String , Object> itemMap) {
        Map<String , Object> map = new HashMap();

        Map<String , Object> currMap = null;

        String curr = null;
        if (fieldName.indexOf(".") > 0) {
            curr = fieldName.substring(0 , fieldName.indexOf("."));
            fieldName = fieldName.substring(fieldName.indexOf(".") + 1);

            currMap = (Map<String, Object>) itemMap.get(curr);
            if (null == currMap ) {
                currMap = new HashMap<>();
            }
            map = initFieldMap(fieldName,sensValue, currMap);
            itemMap.put(curr, map);
        } else {
            itemMap.put(fieldName, sensValue);
        }

        return itemMap;
    }

    public static Map<String, Object> getGwAccessRoleUris(String roleId , String interf) {
        Map<String, Object> map = (Map<String, Object>) getAccessMap().get(roleId);
        if (null != map ) {
            return (Map<String, Object>) map.get(interf);
        }
        return null;
    }

    public static String getGwAccessRoleEndpoint(String roleId , String uri) {
        Map<String, Object> map = (Map<String, Object>) getAccessMap().get(roleId);
        String endPoint = null;
        if (null != map && map.size() > 0) {
            for (Map.Entry<String , Object> entry : map.entrySet()) {
                if (RegexUtils.uriIsExist(entry.getKey(), uri)) {
                    endPoint = entry.getKey();
                    break;
                }
            }
        }
        return endPoint;
    }

    public static String getUnifyInterfServ(String roleId, String interf) {
        Map<String, Object> map = getGwAccessRoleUris(roleId,interf);
        if (null != map ) {
            return (String) map.get(ACCESS_SERVICE_NAME + interf);
        }
        return null;
    }

    public static Map<String, Object> getGwAccessUriMap(String roleId, String interf , String uri) {
        Map<String, Object> interfMap = getGwAccessRoleUris(roleId,interf) ;
        if (null != interfMap) {
            return (Map<String, Object>) interfMap.get(uri);
        }
        return null;
    }

    public static Map<String, Object> getAccessItemMap(String roleId, String interf, String uri, String serviceId) {
        Map<String, Object> uriMap = getGwAccessUriMap(roleId,interf , uri) ;
        if (null != uriMap) {
            return (Map<String, Object>) uriMap.get(ACCESS_SERVICE_ID+(null == serviceId ? "" : serviceId));
        }
        return null;
    }

    public static String getAccessSensIds(String roleId) {
        return (String) getAccessMap().get(ACCESS_SENS_ID + roleId);
    }
    public static String getAccessSensNames(String roleId) {
        return (String) getAccessMap().get(ACCESS_SENS_NAME + roleId);
    }

}
